package com.bsj.media.tool;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.bsj.consumerQ.until.ExceptionUntil;
import com.bsj.media.init.SendCachedData;
import com.bsj.media.init.SendChannelUntil;
import com.bsj.media.network.websocket.CmdDto;
import com.bsj.media.tool.cmd.BackVodInnerParam;
import com.bsj.media.tool.cmd.IRealVideoParamVO;
import com.bsj.power.common.def.dto.media.BackVodCtrolParam;
import com.bsj.power.common.def.dto.media.BackVodParam;
import com.bsj.power.common.def.dto.media.RealVideoParam;
import com.bsj.power.common.def.dto.video.CloseConnectionParam;
import com.bsj.power.common.util.SpringUtil;
import com.bsj.tools.DateUntil;
import lombok.extern.slf4j.Slf4j;
import redis.clients.bsj.JedisClusterBSJ;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


@Slf4j
public class HttpTool {

    private static String mediaCloseUrl = "/video/cmd/closeConnection";

    private static String mediaOpenUrl = "/video/cmd/realVideoReq";

    private static String mediaBackOpenUrl = "/video/cmd/replayReq";

    private static String mediaBackCloseUrl = "/video/cmd/replayControlReq";

//    public static String httpIp = "http://192.168.130.9:7101";

    static JedisClusterBSJ jedisClusterBSJ;

    static VideoCmdUntil videoCmdUntil;

    public static void init(String ip) {
//        httpIp = ip;
        jedisClusterBSJ = (JedisClusterBSJ) SpringUtil.getBean("jedisClusterBSJ");
        videoCmdUntil = (VideoCmdUntil) SpringUtil.getBean("videoCmdUntil");
    }

    public static String get(String path) {
        HttpURLConnection conn = null;
        InputStream is = null;
        String result = "";
        try {
            URL url = new URL(path);
            //打开和url之间的连接
            conn = (HttpURLConnection) url.openConnection();

            /**设置URLConnection的参数和普通的请求属性****start***/

            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");

            /**设置URLConnection的参数和普通的请求属性****end***/

            //设置是否向httpUrlConnection输出，设置是否从httpUrlConnection读入，此外发送post请求必须设置这两个
            //最常用的Http请求无非是get和post，get请求可以获取静态页面，也可以把参数放在URL字串后面，传递给servlet，
            //post与get的 不同之处在于post的参数不是放在URL字串里面，而是放在http请求的正文内。
            conn.setDoOutput(true);
            conn.setDoInput(true);

            conn.setRequestMethod("GET");//GET和POST必须全大写
            /**GET方法请求*****start*/
            /**
             * 如果只是发送GET方式请求，使用connet方法建立和远程资源之间的实际连接即可；
             * 如果发送POST方式的请求，需要获取URLConnection实例对应的输出流来发送请求参数。
             * */
            conn.connect();

            //获取URLConnection对象对应的输入流
            is = conn.getInputStream();
            //构造一个字符流缓存
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String str = "";
            while ((str = br.readLine()) != null) {
                str = new String(str.getBytes(), "UTF-8");//解决中文乱码问题
                result = str + result;
            }
            //关闭流
            is.close();
            //断开连接，最好写上，disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
            //固定多线程的话，如果不disconnect，链接会增多，直到收发不出信息。写上disconnect后正常一些。
            conn.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (conn != null) {
                    conn.disconnect();
                }
                if (is != null) {
                    is.close();
                }
            } catch (IOException ex) {
                log.error(ExceptionUntil.getErrorStr(ex));
            }
        }
        return result;
    }

    /**
     * 直播时使用
     * @param cmdDto
     * @param terminalNo
     * @param channelNo
     * @return
     */
//    public static String cmdLiveMedia(CmdDto cmdDto, String terminalNo, int channelNo) {
//        //0是播放，1是关闭
//        int videoFlag = cmdDto.getVideoFlag();
//        //0是直播，1是回放
//        int videoType = cmdDto.getVideoType();
//        String str = cmdDto.getStr();
//        String simChannel = cmdDto.getSimChannel();
//        //播放
//        if (videoFlag == 0) {
//            return openVideo(simChannel, terminalNo, channelNo, str, videoType);
//            //关闭videoFlag
//        } else if (videoFlag == 1) {
//            int i = SendChannelUntil.closeMediaFlag(simChannel);
//            if (i < 1) {
//                closeMedia(terminalNo, channelNo);
//            }
//            return null;
//        }
//        return null;
//    }

    public static String openVideo(String simChannel, String terminalNo, int channelNo,
                                   String str, int videoType) {
        String result = null;
        SendCachedData sendCachedData = SendChannelUntil.gainObj(simChannel);
        boolean write = false;
        if (sendCachedData == null) {
            //下发播放指令
            handleMediaCmd(terminalNo, channelNo, str, videoType);
            result = UUID.randomUUID().toString();
            write = true;
        } else {
            //无连接状态就下发个指令
            if (sendCachedData.clearFlag()) {
                handleMediaCmd(terminalNo, channelNo, str, videoType);
                result = UUID.randomUUID().toString();
                write = true;
            } else {
                handleMediaCmd(terminalNo, channelNo, str, videoType);
            }
        }
        return result;
    }


    public static void closeMedia(String terminalNo, int channelNo) {
        closeHttp(terminalNo, channelNo);
        String simChannel = terminalNo + "-" + channelNo;
        SendChannelUntil.del(simChannel);
    }

    public static void closeHttp(String terminalNo, int channelNo) {
        //直播关闭
        Map<String, Object> map = new HashMap<>();
        map.put("terminalNo", terminalNo);
        map.put("channelNo", channelNo);
        log.info("关闭指令参数:" + JSONObject.toJSONString(map));
        post(mediaCloseUrl, JSONObject.toJSONString(map));
    }

    public static void liveMediaCmd(String terminalNo, int channelNo, String str) {
        IRealVideoParamVO iRealVideoParamVO = new IRealVideoParamVO();
        iRealVideoParamVO.setDataType(0);
        //5分钟后自动关闭
        iRealVideoParamVO.setCloseTime(0);
        iRealVideoParamVO.setFrom("INNER");
        iRealVideoParamVO.setTerminalNo(terminalNo);
        iRealVideoParamVO.setChannelNo(channelNo);
        String string = JSONObject.toJSONString(iRealVideoParamVO);
        post(mediaOpenUrl, string);
    }

    public static void backMediaCmd(String terminalNo, int channelNo, String str) {
        BackVodInnerParam backVodInnerParam = JSONObject.parseObject(str, BackVodInnerParam.class);
        Integer backType = backVodInnerParam.getBackType();
        //正常直播
        if (backType == null || backType == 0) {
            backVodInnerParam.setSpeed(0);
            backVodInnerParam.setBackType(0);
        } else {
            //快进回放

        }
        backVodInnerParam.setTerminalNo(terminalNo);
        backVodInnerParam.setChannelNo(channelNo);
        backVodInnerParam.setFrom("INNER");
        backVodInnerParam.setDataType(0);
        backVodInnerParam.setStoreType(0);
        String string = JSONObject.toJSONString(backVodInnerParam);
        log.info("调用:" + string);
//        post(httpIp + mediaBackOpenUrl, string, sessionId);
        post(mediaBackOpenUrl, string);
    }

    public static void handleMediaCmd(String terminalNo, int channelNo, String str, int videoType) {
        //直播
        if (videoType == 0) {
            liveMediaCmd(terminalNo, channelNo, str);
            //回放
        } else if (videoType == 1) {

            backMediaCmd(terminalNo, channelNo, str);
        }
    }


    public static String post(String url, String param) {
        log.info("调用接口:" + url);
        /**
         * 这里避免出问题，复用之前的代码，不过根据不同的形式，通过MQ消息发出
         */
        if (url.equals(mediaCloseUrl)) {
            //直播关闭
            CloseConnectionParam closeConnectionParam = JSONObject.parseObject(param, CloseConnectionParam.class);
            videoCmdUntil.closeConnection(closeConnectionParam);
        } else if (url.equals(mediaOpenUrl)) {
            //直播开启
            RealVideoParam realVideoParam = JSONObject.parseObject(param, RealVideoParam.class);
            videoCmdUntil.realVideoReq(realVideoParam);
        } else if (url.equals(mediaBackOpenUrl)) {
            //录像回放开启
            BackVodParam backVodParam = JSONObject.parseObject(param, BackVodParam.class);
            videoCmdUntil.replayReq(backVodParam);
        } else if (url.equals(mediaBackCloseUrl)) {
            //录像回放关闭
            BackVodCtrolParam backVodCtrolParam = JSONObject.parseObject(param, BackVodCtrolParam.class);
            videoCmdUntil.replayControlReq(backVodCtrolParam);
        } else {
            log.warn("url不对:" + url);
        }
        return "";
    }
}
